#include "node_server.h"

#define SERVER_CONFIG "/configs/nodeserver.ini"

bool LoadServerConfig(void)
{
    char m_curProgress_Path[256];

    if(getcwd(m_curProgress_Path,256) == NULL)
    {
        return false;
    } 

    std::string pCurConfigfile = std::string(m_curProgress_Path) + SERVER_CONFIG;

    int servercount = atoi(GetIniSectionItem(pCurConfigfile.c_str(),"serverlist","servercount").c_str());

    for(int i=0;i<servercount;i++) {
        char buf[128];
        sprintf(buf,"ipaddress_%d",i);
        std::string ipaddress = GetIniSectionItem(pCurConfigfile.c_str(),"serverlist",buf);
        sprintf(buf,"port_%d",i);
        int port = atoi(GetIniSectionItem(pCurConfigfile.c_str(),"serverlist",buf).c_str());  

        m_ServerConfigs.insert(std::pair<std::string,tagServerConfig>(ipaddress,tagServerConfig(ipaddress.c_str(),port,NULL)));
    }

    return true;
}

void process_child_servers(void)
{
	if(m_ServerConfigs.empty())
		return;

	std::unordered_map<std::string,tagServerConfig>::iterator iter = m_ServerConfigs.begin();
	for(;iter != m_ServerConfigs.end();++iter) 
	{
		CMolTcpSocketClient *newCMolTcpSocketClient = new CMolTcpSocketClient();
		newCMolTcpSocketClient->Connect((*iter).second.ipaddress,(*iter).second.port);

		if(MolTcpSocketClientManager.addTcpSocketClient(newCMolTcpSocketClient) >= 0) {
			(*iter).second.client = newCMolTcpSocketClient;
		}
	}
}

void suscriptions(int socketid,int type,std::string uniqueid,std::string scription,std::string password)
{
	if(socketid < 0 || scription.empty())
		return;

	int state = 1;

	std::unordered_map<std::string,std::string>::iterator iterPwd = m_SubscribersPwd.find(scription);
	if(iterPwd == m_SubscribersPwd.end()) {		
		m_SubscribersPwd.insert(std::pair<std::string,std::string>(scription,password));
	}
	else {
		if((*iterPwd).second != password) {
			state = 0;	
		}
	}

	if(state == 1) {
		std::map<int,tagSubscriber>::iterator iter = m_Subscribers[scription].find(socketid);
		if(iter == m_Subscribers[scription].end()) {
			m_Subscribers[scription].insert(std::pair<int,tagSubscriber>(socketid,
											tagSubscriber(socketid,uniqueid,scription)));	
		}	
		else {
			state = 2;
		}	
	}

	if(state == 1)
	{
	    Json::Value root;
	    root["MsgId"] = IDD_MESSAGE_SUSCRIPTIONS;
	    root["scription"] = scription;
	    root["password"] = password;	
	    root["uniqueid"] = uniqueid;		

		std::unordered_map<std::string,std::map<int,tagSubscriber> >::iterator iter = m_Subscribers.find(scription);
		std::unordered_map<std::string,std::string>::iterator iterpwd = m_SubscribersPwd.find(scription);
		if(iter != m_Subscribers.end() && 
			(iterpwd != m_SubscribersPwd.end() && (*iterpwd).second == password)) 
		{
			std::map<int,tagSubscriber>::iterator iter2 = (*iter).second.begin();
			for(;iter2 != (*iter).second.end();++iter2) {
			    Sendhtml5((*iter2).first,(char*)root.toStyledString().c_str(),root.toStyledString().length());
			}
		}

		if(type == 0) {
			root["type"] = 1;
			MolTcpSocketClientManager.Sendhtml5(-1,(char*)root.toStyledString().c_str(),root.toStyledString().length());
		}

		LOG_BASIC("%s %s",scription.c_str(),uniqueid.c_str());
	}
}

void unsuscriptions(int socketid,int type,std::string scription)
{
	if(socketid < 0)
		return;

	std::string uniqueid;
	int state = 0;

	if(!scription.empty()) 
	{
		std::unordered_map<std::string,std::map<int,tagSubscriber> >::iterator iter = m_Subscribers.find(scription);
		if(iter != m_Subscribers.end()) {

			if(!(*iter).second.empty()) {
				std::map<int,tagSubscriber>::iterator iter2 = (*iter).second.find(socketid);
				if(iter2 != (*iter).second.end()) {
					uniqueid = (*iter2).second.uniqueid;
					scription = (*iter2).second.subscriptions;
					(*iter).second.erase(iter2);
				}
			}

			if((*iter).second.empty()) {
				std::unordered_map<std::string,std::string>::iterator iterInfo = m_SubscribersPwd.find((*iter).first);
				if(iterInfo != m_SubscribersPwd.end())
					m_SubscribersPwd.erase(iterInfo);

				m_Subscribers.erase(iter);
			}
		}	

		state = 1;
	}

	if(state == 0) {
		std::unordered_map<std::string,std::map<int,tagSubscriber> >::iterator iter = m_Subscribers.begin();
		for(;iter != m_Subscribers.end();) {

			if(!(*iter).second.empty()) {
				std::map<int,tagSubscriber>::iterator iter2 = (*iter).second.find(socketid);
				if(iter2 != (*iter).second.end()) {
					uniqueid = (*iter2).second.uniqueid;
					scription = (*iter2).second.subscriptions;
					(*iter).second.erase(iter2);
				}
			}

			if((*iter).second.empty()) {
				std::unordered_map<std::string,std::string>::iterator iterInfo = m_SubscribersPwd.find((*iter).first);
				if(iterInfo != m_SubscribersPwd.end())
					m_SubscribersPwd.erase(iterInfo);

				iter = m_Subscribers.erase(iter);
			}
			else {
				++iter;
			}
		}
	}

	if(!scription.empty() && !uniqueid.empty()) 
	{
	    Json::Value root;
	    root["MsgId"] = IDD_MESSAGE_UNPUBSCRIPTIONS;
	    root["scription"] = scription;
	    root["uniqueid"] = uniqueid;	

		std::unordered_map<std::string,std::map<int,tagSubscriber> >::iterator iter = m_Subscribers.find(scription);
		if(iter != m_Subscribers.end()) 
		{
			std::map<int,tagSubscriber>::iterator iter2 = (*iter).second.begin();
			for(;iter2 != (*iter).second.end();++iter2) {
			    Sendhtml5((*iter2).first,(char*)root.toStyledString().c_str(),root.toStyledString().length());
			}
		}

		if(type == 0) {
			root["type"] = 1;
			MolTcpSocketClientManager.Sendhtml5(-1,(char*)root.toStyledString().c_str(),root.toStyledString().length());
		}

		LOG_BASIC("%s %s",scription.c_str(),uniqueid.c_str());
	}
}

void public_message(int type,Json::Value &mes)
{
	std::string scription = mes["scription"].asString();	

	std::unordered_map<std::string,std::map<int,tagSubscriber> >::iterator iter = m_Subscribers.find(scription);
	if(iter != m_Subscribers.end()) 
	{
		std::map<int,tagSubscriber>::iterator iter2 = (*iter).second.begin();
		for(;iter2 != (*iter).second.end();++iter2) {
		    Sendhtml5((*iter2).first,(char*)mes.toStyledString().c_str(),mes.toStyledString().length());
		}
	}

	if(type == 0) {
		mes["type"] = 1;
		MolTcpSocketClientManager.Sendhtml5(-1,(char*)mes.toStyledString().c_str(),mes.toStyledString().length());
	}
}